﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace RxjhServer
{
	public class WUserManager<TUser> where TUser : IWUser<string>, new()
	{
		private static volatile bool _initialized;

		private static WUserManager<TUser> _userManager;

		private Dictionary<int, TUser> _users;

		private int _maxUsers;

		public static void Init(int maxUsers)
		{
			if (WUserManager<TUser>._initialized)
			{
				throw new ApplicationException("alread inited");
			}
			WUserManager<TUser>._userManager = new WUserManager<TUser>();
			WUserManager<TUser>._userManager._maxUsers = maxUsers;
			WUserManager<TUser>._userManager._users = new Dictionary<int, TUser>(maxUsers);
			for (int i = 0; i < maxUsers; i++)
			{
				TUser value = (default(TUser) == null) ? Activator.CreateInstance<TUser>() : default(TUser);
				value.Index = i;
				WUserManager<TUser>._userManager._users[i] = value;
			}
			new Thread(new ParameterizedThreadStart(WUserManager<TUser>.threadProce))
			{
				Name = "user manager clearner",
				IsBackground = true,
				Priority = ThreadPriority.Highest
			}.Start();
			WUserManager<TUser>._initialized = true;
		}

		private static void threadProce(object State)
		{
			try
			{
				while (true)
				{
					Dictionary<int, TUser>.ValueCollection values = WUserManager<TUser>._userManager._users.Values;
					foreach (TUser current in values)
					{
						using (current.ReadLock)
						{
							if (!current.Invalid)
							{
								using (current.UpdateLock)
								{
									bool flag = DateTime.Now - current.Timestamp > TimeSpan.FromMinutes(3.0);
									if (flag)
									{
										using (current.WriteLock)
										{
											current.Invalid = true;
										}
									}
								}
							}
						}
					}
					Thread.Sleep(TimeSpan.FromMinutes(1.0));
				}
			}
			catch (Exception)
			{
			}
		}

		public static WUserManager<TUser> GetInstance()
		{
			if (!WUserManager<TUser>._initialized)
			{
				throw new ApplicationException("no init");
			}
			return WUserManager<TUser>._userManager;
		}

		public TUser GetUser(int index, string credentials)
		{
			if (index < 0 || index >= this._maxUsers)
			{
				return default(TUser);
			}
			if (string.IsNullOrEmpty(credentials))
			{
				return default(TUser);
			}
			TUser result = this._users[index];
			using (result.UpdateLock)
			{
				if (!result.Authentication(credentials))
				{
					throw new ApplicationException("Authentication failed");
				}
				if (!result.Invalid)
				{
					using (result.WriteLock)
					{
						result.Timestamp = DateTime.Now;
						return result;
					}
				}
			}
			return default(TUser);
		}

		public TUser AddUser()
		{
			for (int i = 0; i < this._maxUsers; i++)
			{
				TUser result = this._users[i];
				using (result.UpdateLock)
				{
					if (result.Invalid)
					{
						using (result.WriteLock)
						{
							result.Reset();
							result.Invalid = false;
							result.Timestamp = DateTime.Now;
							return result;
						}
					}
				}
			}
			return default(TUser);
		}

		public bool RemoveUser(int index, string credentials)
		{
			if (index < 0 || index >= this._maxUsers)
			{
				return false;
			}
			if (string.IsNullOrEmpty(credentials))
			{
				return false;
			}
			TUser tUser = this._users[index];
			if (tUser == null)
			{
				return false;
			}
			using (tUser.WriteLock)
			{
				tUser.Invalid = true;
			}
			return true;
		}
	}
}
